using System;
using System.Runtime.InteropServices;
using EnvDTE;
using Microsoft.VisualStudio.Project.Automation;
using Microsoft.WowAddonStudio.Project.Automation;

namespace Microsoft.WowAddonStudio.Tests.Common.Mocks
{
	/// <summary>
	/// 
	/// </summary>
	public class MockProjectItem : OAWowFileItem
	{
	    private readonly EnvDTE.Project containingProject;
		private readonly MockProperties properties;
		private readonly string fileName;
		private readonly DTE dte;

        private Document document;
        private string source;

		/// <summary>
		/// Initializes a new instance of the <see cref="MockProjectItem"/> class.
		/// </summary>
		/// <param name="containingProject">The containing project.</param>
		/// <param name="dte">The DTE.</param>
		/// <param name="fileName">Name of the file.</param>
		public MockProjectItem(EnvDTE.Project containingProject, DTE dte, string fileName)
			: this(containingProject, dte, fileName, string.Empty)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="MockProjectItem"/> class.
		/// </summary>
		/// <param name="containingProject">The containing project.</param>
		/// <param name="dte">The DTE.</param>
		/// <param name="fileName">Name of the file.</param>
		/// <param name="source">The source.</param>
		public MockProjectItem(EnvDTE.Project containingProject, DTE dte, string fileName, string source)
			: base(containingProject as OAProject, null)
		{
            this.containingProject = containingProject;
			this.dte = dte;
			this.fileName = fileName;

			document = new MockDocument(dte, source, this);
			properties = new MockProperties(dte, this);
		}

		#region ProjectItem Members

		/// <summary>
		/// Saves the project item.
		/// </summary>
		/// <param name="NewFileName">Required. The file name with which to save the solution, project, or project item. If the file exists, it is overwritten.</param>
		/// <returns>
		/// A Boolean value indicating true if the project item was saved; otherwise, false.
		/// </returns>
		public override bool SaveAs(string NewFileName)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Opens the project item in the specified view. Not implemented because this abstract class dont know what to open
		/// </summary>
		/// <param name="ViewKind">Specifies the view kind in which to open the item</param>
		/// <returns>Window object</returns>
		public override Window Open(string ViewKind)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Removes the project item from hierarchy.
		/// </summary>
		public override void Remove()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Expands the view of Solution Explorer to show project items.
		/// </summary>
		public override void ExpandView()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Saves the project or project item.
		/// </summary>
		/// <param name="FileName">Optional. The name with which to save the project or project item.</param>
		public override void Save(string FileName)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Removes the item from its project and its storage.
		/// </summary>
		public override void Delete()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Returns the dirty state of the document.
		/// </summary>
		/// <value></value>
		/// <exception cref="InvalidOperationException">Is thrown if the project is closed or it the service provider attached to the project is invalid.</exception>
		/// <exception cref="COMException">Is thrown if the dirty state cannot be retrived.</exception>
		public override bool IsDirty
		{
			get { throw new NotImplementedException(); }
			set { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the number of files associated with a ProjectItem.
		/// </summary>
		/// <value></value>
		public override short FileCount
		{
			get { return base.FileCount; }
		}

		/// <summary>
		/// Gets or sets the name of the object.
		/// </summary>
		/// <value></value>
		public override string Name
		{
			get { throw new NotImplementedException(); }
			set { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the ProjectItems collection containing the ProjectItem object supporting this property.
		/// </summary>
		/// <value></value>
		public override ProjectItems Collection
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets a collection of all properties that pertain to the object.
		/// </summary>
		/// <value></value>
		public override Properties Properties
		{
			get { return properties; }
		}

		/// <summary>
		/// Gets the top-level extensibility object.
		/// </summary>
		/// <value></value>
		public override DTE DTE
		{
			get { return dte; }
		}

		/// <summary>
		/// Gets a GUID string indicating the kind or type of the object.
		/// </summary>
		/// <value></value>
		public override string Kind
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the ProjectItems for the object.
		/// </summary>
		/// <value></value>
		public override ProjectItems ProjectItems
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets an object that can be accessed by name at run time.
		/// </summary>
		/// <value></value>
		public new object Object
		{
			get { return source; }
			set
			{
				source = value.ToString();
				document = new MockDocument(DTE, source, this);
			}
		}

		/// <summary>
		/// Gets a list of available Extenders for the object.
		/// </summary>
		/// <value></value>
		public override object ExtenderNames
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the Extender category ID (CATID) for the object.
		/// </summary>
		/// <value></value>
		public override string ExtenderCATID
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets or sets a value indicating whether or not the object has been modified since last being saved or opened.
		/// </summary>
		/// <value></value>
		public override bool Saved
		{
			get { throw new NotImplementedException(); }
			set { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the ConfigurationManager object for this ProjectItem.
		/// </summary>
		/// <value></value>
		/// <remarks>We do not support config management based per item.</remarks>
		public override ConfigurationManager ConfigurationManager
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets FileCodeModel for WowProjectItem
		/// </summary>
		/// <value></value>
		public override FileCodeModel FileCodeModel
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the Document associated with the item, if one exists.
		/// </summary>
		/// <value></value>
		public override Document Document
		{
			get { return document; }
		}

		/// <summary>
		/// If the project item is the root of a subproject, then the SubProject property returns the Project object for the subproject.
		/// </summary>
		/// <value></value>
        public override EnvDTE.Project SubProject
		{
			get { throw new NotImplementedException(); }
		}

	    /// <summary>
	    /// Gets the project hosting the ProjectItem.
	    /// </summary>
	    /// <value></value>
        public override EnvDTE.Project ContainingProject
	    {
            get { return containingProject; }
	    }

		/// <summary>
		/// Gets the full path and names of the files associated with a project item.
		/// </summary>
		/// <param name="index">The index of the item</param>
		/// <returns>The full path of the associated item</returns>
		/// <exception cref="ArgumentOutOfRangeException">Is thrown if index is not one</exception>
		public override string get_FileNames(short index)
		{
			return fileName;
		}

		/// <summary>
		/// Get_s the is open.
		/// </summary>
		/// <param name="ViewKind">Kind of the view.</param>
		/// <returns></returns>
		public override bool get_IsOpen(string ViewKind)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Get_s the extender.
		/// </summary>
		/// <param name="ExtenderName">Name of the extender.</param>
		/// <returns></returns>
		public override object get_Extender(string ExtenderName)
		{
			throw new NotImplementedException();
		}

		#endregion

		/// <summary>
		/// Sets the document.
		/// </summary>
		/// <param name="doc">The doc.</param>
		public void SetDocument(Document doc)
		{
			document = doc;
		}
	}
}